package View;

import com.cqtczh.qhd.driver.R;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;

/**
 * * @author 作者 陈修园:
 * 
 * @date 创建时间：2015-5-28 上午10:16:05
 * @version 1.0
 * @parameter
 * @since
 * @return
 */
public abstract class TouchMoveToZoomBase<T extends View> extends LinearLayout
		implements Ipulltozoom<T> {
	private static final float FRICITION = 2.0f;

	protected T mRootView;
	protected View mHeaderView;
	protected View mZoomView;

	protected int mScreenHeight;
	protected int mScreenWidth;

	private boolean isZoomEnabled = true;

	private boolean isParallax = true;

	private boolean isZooming = false;

	private boolean isHideHeader = false;

	private int mTouchSlop;

	private boolean mIsBeingDragged = false;

	private float mLastMotionY;

	private float mLastMotionX;

	private float mInitialMotionY;

	private float mInitialMotionX;

	private OnPullZoomListener onPullZoomListener;

	public TouchMoveToZoomBase(Context context) {
		this(context, null);
		init(context, null);
	}

	public TouchMoveToZoomBase(Context context, AttributeSet attrs) {
		 super(context, attrs);
		 init(context, attrs);
		
	}

	private void init(Context context, AttributeSet attrs) {
		// 控件居中
		setGravity(Gravity.CENTER);
		ViewConfiguration configuration = ViewConfiguration.get(context);
		/*
		 * 是一个距离，表示滑动的时候，手的移动要大于这个距离才开始移动控件。 如果小于这个距离就不触发移动控件，
		 * 如viewpager就是用这个距离来判断用户是否翻页
		 */
		mTouchSlop = configuration.getScaledTouchSlop();
		// 获取屏幕宽高
		DisplayMetrics locaDisplayMetrics = new DisplayMetrics();
		 WindowManager mWm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
		mWm.getDefaultDisplay().getMetrics(locaDisplayMetrics);
		// ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(locaDisplayMetrics);
		//mScreenHeight = getContext().getw
		//mScreenWidth = this.getWidth();
		//Log.v("mScreenHeight", ""+mScreenHeight);
		//Log.v("mScreenHeight", ""+mScreenWidth);
		mScreenHeight = locaDisplayMetrics.heightPixels;
		mScreenWidth = locaDisplayMetrics.widthPixels;
		Log.v("mScreenHeight", ""+mScreenHeight);
		Log.v("mScreenHeight", ""+mScreenWidth);
		// Refreshable View
		// By passing the attrs, we can add ListView/GridView params via XML
		// 定义显示的view
		mRootView = createRootView(context, attrs);

		if (attrs != null) {
			LayoutInflater mLayoutInflater = LayoutInflater.from(getContext());
			// 初始化状态View
			TypedArray a = getContext().obtainStyledAttributes(attrs,
					R.styleable.PullToZoomView);
			int zoomViewResId = a.getResourceId(
					R.styleable.PullToZoomView_zoomView, 0);
			if (zoomViewResId > 0) {
				mZoomView = mLayoutInflater.inflate(zoomViewResId, null, false);
			}

			int headerViewResId = a.getResourceId(
					R.styleable.PullToZoomView_headerView, 0);
			if (headerViewResId > 0) {
				mHeaderView = mLayoutInflater.inflate(headerViewResId, null,
						false);
			}

			isParallax = a.getBoolean(
					R.styleable.PullToZoomView_isHeaderParallax, true);
			handleStyLedAttributes(a);
			a.recycle();
		}
		addView(mRootView, ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.MATCH_PARENT);
	}

	public void SetOnPullZoomListener(OnPullZoomListener onPullZoomListener) {
		this.onPullZoomListener = onPullZoomListener;

	}

	@Override
	public T getPullRootView() {
		return mRootView;
	}

	@Override
	public View getZoomView() {
		return mZoomView;
	}

	@Override
	public View getHeaderView() {
		return mHeaderView;
	}

	@Override
	public boolean isPullToZoomEnabled() {
		return isZoomEnabled;
	}

	@Override
	public boolean isZooming() {
		return isZooming;
	}

	@Override
	public boolean isParallax() {
		return isParallax;
	}

	@Override
	public boolean isHideHeader() {
		return isHideHeader;
	}

	public void setZoomEnabled(boolean isZoomEnabled) {
		this.isZoomEnabled = isZoomEnabled;
	}

	public void setParallax(boolean isParallax) {
		this.isParallax = isParallax;
	}

	public void setHideHeader(boolean isHideHeader) {
		this.isHideHeader = isHideHeader;
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		/*
		 * MotionEvent.ACTION_DOWN 当屏幕检测到第一个触点按下之后就会触发到这个事件。
		 * 
		 * MotionEvent.ACTION_MOVE：当触点在屏幕上移动时触发，触点在屏幕上停留也是会触发的，
		 * 主要是由于它的灵敏度很高，而我们的手指又不可能完全静止（即使我们感觉不到移动， 但其实我们的手指也在不停地抖动）。
		 * 
		 * MotionEvent.ACTION_POINTER_DOWN：当屏幕上已经有触点处于按下的状态的时候， 再有新的触点被按下时触发。
		 * 
		 * MotionEvent.ACTION_POINTER_UP：当屏幕上有多个点被按住， 松开其中一个点时触发（即非最后一个点被放开时）触发。
		 * 
		 * MotionEvent.ACTION_UP：当最后一个触点松开时被触发。
		 * 
		 * MotionEvent.ACTION_SCROLL：非触摸滚动，主要是由鼠标、滚轮、轨迹球触发。
		 * 
		 * MotionEvent.ACTION_CANCEL：不是由用户直接触发，有系统再需要的时候触发， 例如当父view通过使函数
		 * 
		 * onInterceptTouchEvent()返回true,从子view拿回处理事件的控制权是，
		 * 就会给子view发一个ACTION_CANCEL事件， 这里了view就再也不会收到事件了。可以将其视为ACTION_UP事件对待。
		 */

		if (!isPullToZoomEnabled() || isHideHeader()) {
			return false;
		}
		final int action = ev.getAction();
		if (action == MotionEvent.ACTION_CANCEL
				|| action == MotionEvent.ACTION_UP) {
			mIsBeingDragged = false;
			return false;
		}

		if (action != MotionEvent.ACTION_DOWN && mIsBeingDragged) {
			return true;
		}

		switch (action) {
		case MotionEvent.ACTION_MOVE: {
			if (isReadyForPullStart()) {
				final float y = ev.getY(), x = ev.getX();
				final float diff, oppositeDiff, absDiff;
				diff = y - mLastMotionY;
				oppositeDiff = x - mLastMotionX;
				absDiff = Math.abs(diff);
				if (absDiff > mTouchSlop && absDiff > Math.abs(oppositeDiff)) {
					if (diff >= 1f && isReadyForPullStart()) {
						mLastMotionX = x;
						mLastMotionY = y;
						mIsBeingDragged = true;
					}
				}
			}
			break;
		}
		case MotionEvent.ACTION_DOWN: {
			if (isReadyForPullStart()) {
				mLastMotionX = mInitialMotionY = ev.getX();
				mLastMotionY = mInitialMotionY = ev.getY();
				mIsBeingDragged = false;
			}
			break;
		}
		}

		return mIsBeingDragged;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		if (!isPullToZoomEnabled() || isHideHeader()) {
			return false;
		}

		if (event.getAction() == MotionEvent.ACTION_DOWN
				&& event.getEdgeFlags() != 0) {
			return false;
		}

		switch (event.getAction()) {
		case MotionEvent.ACTION_MOVE:
			if (mIsBeingDragged) {
				mLastMotionY = event.getY();
				mLastMotionX = event.getX();
				pullEvent();
				isZooming = true;
				return true;
			}
			break;

		case MotionEvent.ACTION_DOWN: {
			if (isReadyForPullStart()) {
				mLastMotionX = mInitialMotionX = event.getX();
				mLastMotionY = mInitialMotionY = event.getY();
				return true;
			}
			break;
		}

		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP: {
			if (mIsBeingDragged) {
				mIsBeingDragged = false;
				if (isZooming()) {
					smoothScrollToTop();
					if (onPullZoomListener != null) {
						onPullZoomListener.onPullZoomEnd();
					}
					isZooming = false;
					return true;
				}
				return true;
			}
			break;
		}
		}

		return false;
	}

	private void pullEvent() {
		final int newScrollValue;
		final float initialMotionValue, lastMotionValue;

		initialMotionValue = mInitialMotionY;
		lastMotionValue = mLastMotionY;
		newScrollValue = Math.round(Math.min(initialMotionValue
				- lastMotionValue, 0)
				/ FRICITION);
		pullHeaderToZoom(newScrollValue);
		if (onPullZoomListener != null) {
			onPullZoomListener.onPullZooming(newScrollValue);
		}
	}

	public interface OnPullZoomListener {
		public void onPullZooming(int newScrollValue);

		public void onPullZoomEnd();
	}

	protected abstract void pullHeaderToZoom(int newScrollValue);

	protected abstract T createRootView(Context context,
			AttributeSet attributeSet);

	protected abstract boolean isReadyForPullStart();

	protected abstract void smoothScrollToTop();

	public abstract void setHeaderView(View headerView);

	public abstract void setZoomView(View zoomView);
}
